using System;
using System.IO;
using System.Linq;
using System.Text;
using Cfg.Exceptions;

namespace Cfg.ConfigProviders
{
    public class IniFileProvider : ConfigFileProviderBase
    {
        public char NameValueDelimiter = '=';

        public override string[] VariablePatterns
        {
            get { return null; }
        }

        public IniFileProvider(string path) : base(path)
        {
            AppSettings.Settings.Parsers.Clear();

            AppSettings.Settings.AddParser(x =>
            {
                var trueValues = new[] {"1", "true", "on", "yes"};
                var falseValues = new[] {"0", "false", "off", "no"};

                if (trueValues.Contains(x, StringComparer.InvariantCultureIgnoreCase))
                    return true;

                if (falseValues.Contains(x, StringComparer.InvariantCultureIgnoreCase))
                    return false;

                throw new InvalidFormatException("Value '" + x + "' could not be converted to boolean");
            });
        }

        public void Save()
        {
            // todo - save ini file to Path
        }

        public override ConfigKeyValues GetValues()
        {
            var lines = File.ReadAllLines(Path);
            var kvps = new ConfigKeyValues();

            var escapedNameValueDelimiter = @"\" + NameValueDelimiter;
            var escapedNameValueDelimiterReplacement = new string('\u0888', 1);

            string prefix = string.Empty;
            foreach (var line in lines)
            {
                var trimmedLine = line.Trim();

                if (trimmedLine.Length == 0)
                    continue;

                // comment
                if (trimmedLine[0] == ';' || trimmedLine[0] == '#')
                    continue;

                if (trimmedLine[0] == '[')
                {
                    prefix = trimmedLine.Substring(1, trimmedLine.Length - 2) + ".";
                    continue;
                }

                var keyValuePair = line
                    .Replace(escapedNameValueDelimiter, escapedNameValueDelimiterReplacement)
                    .Split(NameValueDelimiter);

                var key = prefix + keyValuePair[0];
                kvps[key] = keyValuePair[1]
                    .Replace(escapedNameValueDelimiterReplacement, escapedNameValueDelimiter)
                    .Replace("\\", "")
                    .Trim('"');
            }

            return kvps;
        }
    }
}